# -*- coding: utf-8 -*-
"""
类型转换工具 - 处理LLM返回的参数值类型转换

@author: AI Assistant
"""
from typing import Any, Dict
from loguru import logger


def convert_parameter_value(value: Any, expected_type: str) -> Any:
    """转换参数值到期望的类型
    
    Args:
        value: 原始值
        expected_type: 期望的类型（'float', 'int', 'str', 'bool', 'array', 'object'）
        
    Returns:
        转换后的值
    """
    # 如果值已经是期望类型，直接返回
    if expected_type == "float" and isinstance(value, (int, float)):
        return float(value)
    elif expected_type == "int" and isinstance(value, int):
        return value
    elif expected_type == "str" and isinstance(value, str):
        return value
    elif expected_type == "bool" and isinstance(value, bool):
        return value
    elif expected_type == "array" and isinstance(value, list):
        return value
    elif expected_type == "object" and isinstance(value, dict):
        return value
    
    # 尝试类型转换
    try:
        if expected_type == "float":
            # 字符串转float
            if isinstance(value, str):
                return float(value)
            elif isinstance(value, (int, float)):
                return float(value)
        
        elif expected_type == "int":
            # 字符串转int
            if isinstance(value, str):
                return int(float(value))  # 先转float再转int，处理 "1.0" 这种情况
            elif isinstance(value, (int, float)):
                return int(value)
        
        elif expected_type == "bool":
            # 字符串转bool
            if isinstance(value, str):
                return value.lower() in ('true', '1', 'yes')
            elif isinstance(value, (int, float)):
                return bool(value)
        
        elif expected_type == "str":
            # 任何类型转字符串
            return str(value)
        
        # array和object不做转换
        return value
        
    except Exception as e:
        logger.warning(f"类型转换失败: {value} -> {expected_type}, 错误: {e}")
        return value


def normalize_parameter_changes(
    parameter_changes: Dict[str, Any],
    para_schema: Dict[str, Any]
) -> Dict[str, Any]:
    """标准化参数修改的值类型
    
    Args:
        parameter_changes: 参数修改字典
        para_schema: 参数模式定义
        
    Returns:
        标准化后的参数修改字典
    """
    normalized = {}
    
    for param_path, value in parameter_changes.items():
        # 解析参数路径
        parts = param_path.split(".")
        if len(parts) < 2:
            normalized[param_path] = value
            continue
        
        category = parts[0]
        param_name_with_index = parts[1]
        
        # 提取参数名（去除数组索引）
        import re
        param_name_match = re.match(r'^([^\[]+)', param_name_with_index)
        param_name = param_name_match.group(1) if param_name_match else param_name_with_index
        
        # 获取参数定义
        param_def = para_schema.get(category, {}).get(param_name)
        
        if param_def:
            expected_type = param_def.get("type", "float")
            
            # 对于数组元素修改，检测实际值类型
            if '[' in param_name_with_index:
                # 数组元素修改，尝试转换为数值
                if isinstance(value, str):
                    # 尝试转换为float
                    try:
                        float(value)
                        expected_type = "float"
                    except ValueError:
                        expected_type = "str"
                elif isinstance(value, (int, float)):
                    expected_type = "float"
            else:
                # 整个参数修改，动态检测类型
                if isinstance(value, list):
                    expected_type = "array"
                elif isinstance(value, dict):
                    expected_type = "object"
            
            # 转换类型
            converted_value = convert_parameter_value(value, expected_type)
            normalized[param_path] = converted_value
            
            # 记录转换
            if type(value) != type(converted_value):
                logger.info(f"类型转换: {param_path} - {type(value).__name__}({value}) -> {type(converted_value).__name__}({converted_value})")
        else:
            # 没有定义，保持原值
            normalized[param_path] = value
    
    return normalized


# 使用示例
if __name__ == "__main__":
    # 测试类型转换
    print("测试类型转换:")
    print(f"字符串 '0.5' -> float: {convert_parameter_value('0.5', 'float')}")
    print(f"字符串 '10' -> int: {convert_parameter_value('10', 'int')}")
    print(f"字符串 'true' -> bool: {convert_parameter_value('true', 'bool')}")
    print(f"整数 1 -> float: {convert_parameter_value(1, 'float')}")
    
    # 测试标准化
    print("\n测试标准化:")
    para_schema = {
        "parameters": {
            "K": {"type": "float", "min": 0.1, "max": 0.9},
            "A": {"type": "float", "min": 0, "max": 5}
        }
    }
    
    parameter_changes = {
        "parameters.K": "0.5",  # 字符串
        "parameters.A": 3.5     # 数字
    }
    
    normalized = normalize_parameter_changes(parameter_changes, para_schema)
    print(f"原始: {parameter_changes}")
    print(f"标准化: {normalized}")
    print(f"K的类型: {type(normalized['parameters.K'])}")
    print(f"A的类型: {type(normalized['parameters.A'])}")
